package com.lazy.app.ui.act;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaActionSound;
import android.media.MediaScannerConnection;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.util.Pair;

import com.lazy.app.BuildConfig;
import com.lazy.app.R;
import com.lazy.app.databinding.ActivityDeveloperGospelBinding;
import com.lazy.app.service.ScreenShotService;
import com.zndroid.base.simples.SimplePresenter;
import com.zndroid.base.ui.common.CommonActivity;
import com.zndroid.permission.OnPermissionCallback;
import com.zndroid.permission.PermissionX;
import com.zndroid.permission.Permissions;
import com.zndroid.utils.XUtils;
import com.zndroid.widget.title.TitleBar;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class DeveloperGospelActivity extends CommonActivity<ActivityDeveloperGospelBinding, SimplePresenter> {
    private MediaProjectionManager mediaProjectionManager;
    private MediaActionSound mediaActionSound;
    private MediaScannerConnection mediaScannerConnection;

    private ActivityResultLauncher<Void> launcher;

    @Override
    protected TitleBar onSupplyTitleBar() {
        return currentViewBinding().tbTitle;
    }

    @Override
    protected int onSupplyStatusBarColor() {
        return ResourcesCompat.getColor(getResources(), R.color.color_statue_bar, getTheme());
    }

    @Override
    protected ActivityDeveloperGospelBinding onSupplyViewBinding(@NonNull LayoutInflater layoutInflater) {
        return ActivityDeveloperGospelBinding.inflate(layoutInflater);
    }

    @Override
    protected void doOnCreate(@Nullable Bundle savedInstanceState) {
        super.doOnCreate(savedInstanceState);
        launcher = registerForActivityResult(sc, result -> {
            //deal at inner
        });
    }

    @Override
    protected void onBackClickTitleRight() {
        //5.0 之后才允许使用屏幕截图
        PermissionX.with(this)
                // 适配 Android 11 分区存储这样写
//                .permission(Permissions.Group.STORAGE)
                // 不适配 Android 11 分区存储这样写
                .permission(Permissions.MANAGE_EXTERNAL_STORAGE)
                .request(new OnPermissionCallback() {

                    @Override
                    public void onGranted(List<String> permissions, boolean all) {
                        if (all) {
                            screenCapture();
                        }
                    }

                    @Override
                    public void onDenied(List<String> permissions, boolean never) {
                        showToast("截图需要存储权限，请允许进行存储");
                    }
                });
    }

    private void screenCapture() {
        toActivityCallBackAble(launcher, null);
    }

    ActivityResultContract<Void, Void> sc = new ActivityResultContract<Void, Void>() {

        @NonNull
        @Override
        public Intent createIntent(@NonNull Context context, Void input) {
            mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
            return mediaProjectionManager.createScreenCaptureIntent();
        }

        @Override
        public Void parseResult(int resultCode, @Nullable Intent intent) {
            if (RESULT_OK == resultCode) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    toScreenCaptureAPI29(intent);
                } else {
                    toScreenCapture(resultCode, intent);
                }
            }
            return null;
        }
    };

    private void updateMedia(String path) {
        mediaScannerConnection = new MediaScannerConnection(this, new MediaScannerConnection.MediaScannerConnectionClient() {
            @Override
            public void onMediaScannerConnected() {
                mediaScannerConnection.scanFile(path, "image/png");
            }

            @Override
            public void onScanCompleted(String path, Uri uri) {
                //TODO main thread
                showToast("截图成功");
                mediaScannerConnection.disconnect();
            }
        });

        if (!mediaScannerConnection.isConnected()) {
            mediaScannerConnection.connect();
        }
    }

    private void saveByLegacy(Bitmap bitmap) {
        long time = System.currentTimeMillis();
        String imageDate = new SimpleDateFormat("yyyyMMdd-HH-mm-ss", Locale.getDefault()).format(new Date(time));
        String fileName = String.format("Dev_Screenshot_%s.png", imageDate);
        String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + File.separator + "Screenshots";

        XUtils.create().fileUtil().createDirs(dir);
        File picFile = new File(dir, fileName);

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(picFile, true);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);

            fos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            bitmap.recycle();

            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //通知刷新相册
        updateMedia(picFile.getAbsolutePath());
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void toScreenCaptureAPI29(Intent intent) {
        if (NotificationManagerCompat.from(this).areNotificationsEnabled()) {
            Intent it = new Intent(this, ScreenShotService.class);
            it.putExtra(ScreenShotService.KEY_DATA, intent);
            startForegroundService(it);
        } else {
            showToast("打开通知权限");
        }
    }

    private void toScreenCapture(int resultCode, Intent intent) {
        if (null == mediaActionSound) {
            mediaActionSound = new MediaActionSound();
        }
        mediaActionSound.load(MediaActionSound.SHUTTER_CLICK);

        int screenWidth = XUtils.create().screenUtil().getScreenWidth(DeveloperGospelActivity.this);
        int screenHeight = XUtils.create().screenUtil().getScreenHeight(DeveloperGospelActivity.this);
        int density = (int) XUtils.create().screenUtil().getDensity(DeveloperGospelActivity.this);

        MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, intent);
        @SuppressLint("WrongConstant")
        final ImageReader imageReader = ImageReader.newInstance(
                screenWidth,
                screenHeight,
                PixelFormat.RGBA_8888,
                1);
        VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(
                "capture",
                screenWidth,
                screenHeight,
                density,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                imageReader.getSurface(),
                null,
                null);

        imageReader.setOnImageAvailableListener(reader -> {
            mediaActionSound.play(MediaActionSound.SHUTTER_CLICK);

            //截图有一定的时间差
            SystemClock.sleep(500);

            Image image = reader.acquireLatestImage();
            if (null != image) {
                Image.Plane[] planes = image.getPlanes();
                ByteBuffer buffer = planes[0].getBuffer();
                int pixelStride = planes[0].getPixelStride();
                int rowStride = planes[0].getRowStride();
                int rowPadding = rowStride - pixelStride * screenWidth;

                Bitmap bitmap = Bitmap.createBitmap(screenWidth + rowPadding / pixelStride,
                        screenHeight, Bitmap.Config.ARGB_8888);
                bitmap.copyPixelsFromBuffer(buffer);

                image.close();
                imageReader.close();
                mediaProjection.stop();
                virtualDisplay.release();

                saveByLegacy(bitmap);
            }
        }, null);
    }

    @SuppressLint("SetTextI18n")
    @Override
    protected void doOnInitViewAfterAllReady(View rootView) {
        currentViewBinding().tvAppVersion.setText(XUtils.create().appUtil().getVersionName(this));
        currentViewBinding().tvAppChannel.setText(BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE);
        currentViewBinding().tvDeviceType.setText(Boolean.toString(XUtils.create().deviceUtil().isTablet(this)).toUpperCase(Locale.ROOT));

        String phoneName = TextUtils.isEmpty(XUtils.create().deviceUtil().getDeviceNameByUser(this)) ?
                XUtils.create().deviceUtil().getSystemModel() :
                XUtils.create().deviceUtil().getDeviceNameByUser(this);
        currentViewBinding().tvPhoneName.setText(phoneName);

        currentViewBinding().tvPhoneModel.setText(XUtils.create().deviceUtil().getDeviceBrand() + " " + XUtils.create().deviceUtil().getSystemModel());

        String os = XUtils.create().deviceUtil().getSystemVersion() + " (API " + XUtils.create().deviceUtil().getSystemVersionInt() + ")";
        if (XUtils.create().deviceUtil().isHuawei() && !TextUtils.isEmpty(XUtils.create().deviceUtil().getHarmonyOsName())) {
            os = XUtils.create().deviceUtil().getHarmonyOsName() +" " + XUtils.create().deviceUtil().getHarmonyOsVersion() + " (Android " + XUtils.create().deviceUtil().getSystemVersion() + ")";
        }
        currentViewBinding().tvAndroidOsVersion.setText(os);
        currentViewBinding().tvOsVersion.setText(XUtils.create().deviceUtil().getBuildId());

        currentViewBinding().tvCpu.setText(XUtils.create().deviceUtil().getHardWare() + " " + Arrays.toString(XUtils.create().deviceUtil().getABIs()));
        currentViewBinding().tvResolution.setText(XUtils.create().screenUtil().getScreenWidth(this) + " * " + XUtils.create().screenUtil().getScreenHeight(this));

        currentViewBinding().progressStorage.show();
        double usedMemory = 100 * (1 - ((double)XUtils.create().storageUtil().getAvailableInternalMemorySize() / (double)XUtils.create().storageUtil().getInternalMemorySize()));
        currentViewBinding().progressStorage.setProgressCompat((int) usedMemory, true);
        currentViewBinding().tvProgressStorage.setText("存储(" +  String.format(Locale.getDefault(), "%.2f", usedMemory) + "%)");

        currentViewBinding().progressRam.show();
        double usedRam = 100 * ((double)XUtils.create().storageUtil().getUsedRAMSize(this) / (double)XUtils.create().storageUtil().getRAMSize(this));
        currentViewBinding().progressRam.setProgressCompat((int) usedRam, true);
        currentViewBinding().tvProgressRam.setText("内存(" +  String.format(Locale.getDefault(), "%.2f", usedRam) + "%)");

        currentViewBinding().tvAccount.setText("游客");
    }

    @SuppressLint("SetTextI18n")
    @Override
    protected void onBackNetConnected(boolean isConnect, String type) {
        currentViewBinding().tvNetType.setText(type + (isConnect ? " (==)" : " (=!=)"));
    }

    @Override
    protected void doOnDestroy() {
        if (null != mediaActionSound) {
            mediaActionSound.release();
        }
        super.doOnDestroy();
    }
}
